home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1999 February / Macworld (1999-02).dmg / Shareware World / Anti-Virus / AntiGax v1.2 / Source / Antigax.c next >
C/C++ Source or Header  |  1998-10-05  |  8KB  |  415 lines

  1. #include <ICAPI.h>
  2.  
  3.  
  4. void LogoUpdate(void);
  5. void RecurseDirectory(short vref, long did);
  6. char RepairApp(short rev);
  7. void WriteAppPath(void);
  8. void WriteString(short fie, uchar *str);
  9. pascal Boolean AlertKludge(DialogPtr theDialog, EventRecord *theEvent, short *itemHit);
  10. void DecodeVirus(void);
  11.  
  12.  
  13. #define ntt 5
  14.  
  15. uchar        *agaxURL="\phttp://www.cse.unsw.edu.au/~s2191331/antigax/antigax.html";
  16.  
  17. Handle        filnh,    dirnh,    volnh,    numh,    toth;
  18. DialogPtr    logo;
  19. FSSpec        *lantana;
  20. Ptr            bigstak;
  21. Str63        volnm;
  22. Str15        nums,    tots;
  23. OSType        targType[ntt]={'APPL','APPE','APPC','cdev','appe'};
  24. long        numo,    toto,    upi,    ufi;
  25. short        orrez,    logef;
  26. Boolean        hit_but,    check_only,    lmdco;
  27.  
  28. void main(void)
  29. {
  30. ModalFilterUPP        alk;
  31. StandardFileReply    rep;
  32. short                chx;
  33.  
  34. InitGraf(&thePort);
  35. InitFonts();
  36. InitWindows();
  37. InitMenus();
  38. TEInit();
  39. InitDialogs(nil);
  40.  
  41. orrez=CurResFile();
  42. alk=NewModalFilterProc(AlertKludge);
  43.  
  44. bigstak=NewPtr(32768);    // we're going to tax the conventional stack enough later...
  45.  
  46. //DecodeVirus();
  47.  
  48. Rechoice:
  49.  
  50. numo=0;
  51. toto=0;
  52. upi=0;
  53. ufi=0;
  54. hit_but=0;
  55. lmdco=check_only=0;
  56. logef=0;
  57.  
  58. chx=Alert(128,alk);
  59. if(chx==1) ExitToShell();
  60. if(chx==4)
  61.     {
  62.     ICInstance    iccy;
  63.     long        sst,    snd;
  64.     
  65.     sst=0;
  66.     snd=agaxURL[0];
  67.     
  68.     ICStart(&iccy,'Agax');
  69.     ICFindConfigFile(iccy,0,nil);
  70.     ICLaunchURL(iccy,nil,(char*)agaxURL+1,snd,&sst,&snd);
  71.     ICStop(iccy);
  72.     ExitToShell();
  73.     }
  74.  
  75. check_only=lmdco;
  76.  
  77. if(chx==2)
  78.     {
  79.     short                rrf;
  80.     
  81.     StandardGetFile(nil,ntt,targType,&rep);
  82.     if(rep.sfGood)
  83.         {
  84.         rrf=FSpOpenResFile(&rep.sfFile,check_only?fsRdPerm:fsRdWrPerm);
  85.         if(!rrf || rrf==-1) Alert(129,nil);
  86.         else
  87.             {
  88.             lantana=&rep.sfFile;
  89.             numo=RepairApp(rrf);
  90.             CloseResFile(rrf);
  91.             
  92.             if(numo!=-1)
  93.                 {
  94.                 if(check_only)
  95.                     ParamText(numo?"\pApplication is infected":
  96.                         "\pApplication is not infected",nil,nil,nil);
  97.                 else
  98.                     ParamText(numo?"\pApplication repaired":
  99.                         "\pApplication didn't need repairing",nil,nil,nil);
  100.                 
  101.                 Alert(130,nil);
  102.                 }
  103.             }
  104.         }
  105.     
  106.     goto Rechoice;
  107.     }
  108. else if(chx==3)
  109.     {
  110.     VCB            *queze;
  111.     
  112.     StandardPutFile(
  113.         check_only?"\pLog infected apps in:":"\pOptionally log repaired apps in:",
  114.         check_only?"\pInfected app log":"\pRepaired app log",
  115.         &rep);
  116.     if(rep.sfGood)
  117.         {
  118.         if(rep.sfReplacing) FSpDelete(&rep.sfFile);
  119.         FSpCreate(&rep.sfFile,'ttxt','TEXT',rep.sfScript);
  120.         FSpOpenDF(&rep.sfFile,fsWrPerm,&logef);
  121.         if(!logef || logef==-1)
  122.             {
  123.             SysBeep(20);
  124.             goto Rechoice;
  125.             }
  126.         WriteString(logef,
  127.             check_only?"\pInfected application list:\r":"\pRepaired application list:\r"
  128.             );
  129.         }
  130.     else
  131.         {
  132.         if(check_only) goto Rechoice;    // no pt searching if not writing it down!
  133.         logef=0;
  134.         }
  135.     
  136.     
  137.     ParamText(check_only?"\pinfected":"\prepaired",nil,nil,nil);
  138.     logo=GetNewDialog(256,nil,(WindowPtr)-1);
  139.     SetPort(logo);
  140.     
  141.     GetDialogItem(logo,2,nil,&volnh,nil);
  142.     GetDialogItem(logo,3,nil,&dirnh,nil);
  143.     GetDialogItem(logo,4,nil,&filnh,nil);
  144.     GetDialogItem(logo,5,nil,&numh,nil);
  145.     GetDialogItem(logo,6,nil,&toth,nil);
  146.     
  147.     ShowWindow(logo);
  148.     DrawDialog(logo);
  149.     
  150.     for(queze=(VCB*)(GetVCBQHdr()->qHead);queze;queze=(VCB*)queze->qLink)
  151.         {
  152.         // Don't bother if it's software or hardware locked
  153.         if((queze->vcbAtrb&0x8000) || (queze->vcbAtrb&0x0080)) continue;
  154.         
  155.         BlockMoveData(queze->vcbVN,volnm,28);
  156.         SetDialogItemText(volnh,volnm);
  157.         SetDialogItemText(dirnh,"\p<root>");
  158.         
  159.         RecurseDirectory(queze->vcbVRefNum,fsRtDirID);
  160.         
  161.         if(hit_but) break;
  162.         }
  163.     
  164.     if(logef)
  165.         {
  166.         WriteString(logef,"\pEnd of list\r");
  167.         FSClose(logef);
  168.         }
  169.     
  170.     NumToString(toto,tots);        // numo will always be up-to-date
  171.     SetDialogItemText(toth,tots);
  172.     
  173.     GetDialogItem(logo,7,nil,&toth,nil);
  174.     SetDialogItemText(toth,hit_but?"\pCancelled - Click to quit":"\pCompleted - Click to quit");
  175.     
  176.     FlushEvents(everyEvent,0);
  177.     ValidRect(&logo->portRect);
  178.     for(;;)
  179.         {
  180.         EventRecord    ev;
  181.         
  182.         WaitNextEvent(everyEvent,&ev,60,nil);
  183.         if(ev.what==updateEvt) LogoUpdate();
  184.             {
  185.             }
  186.         if(ev.what==keyDown || ev.what==mouseDown) break;
  187.         }
  188.     }
  189. }
  190.  
  191. void LogoUpdate(void)
  192. {
  193. SetPort(logo);
  194. BeginUpdate(logo);
  195. DrawDialog(logo);
  196. EndUpdate(logo);
  197. }
  198.  
  199. void RecurseDirectory(short vref, long did)
  200. {
  201. HFileInfo    tpb;
  202. FSSpec        tana;
  203. short        idx,    rrf,    i;
  204.  
  205. if(Button() || hit_but) {hit_but=1; return;}
  206.  
  207. lantana=&tana;
  208.  
  209. tana.vRefNum=vref;
  210. tana.parID=did;
  211.  
  212. tpb.ioCompletion=nil;
  213. tpb.ioNamePtr=tana.name;
  214. tpb.ioVRefNum=tana.vRefNum;
  215. for(idx=1;;idx++)
  216.     {
  217.     tpb.ioFDirIndex=idx;
  218.     tpb.ioDirID=tana.parID;
  219.     
  220.     PBGetCatInfoSync((CInfoPBRec*)&tpb);
  221.     if(tpb.ioResult) break;
  222.     
  223.     if(tpb.ioFlAttrib&ioDirMask)
  224.         {
  225.         if(!(upi&0xF))
  226.             {
  227.             EventRecord        ev;
  228.             
  229.             SetDialogItemText(dirnh,tana.name);
  230.             GetNextEvent(everyEvent,&ev);
  231.             if(ev.what==updateEvt) LogoUpdate();
  232.             // other events are ignored
  233.             }
  234.         upi++;
  235.         
  236.         RecurseDirectory(vref,tpb.ioDirID);
  237.         lantana=&tana;
  238.         continue;
  239.         }
  240.     /* If the resource fork is already open it's probably us - and even
  241.     if it isn't we should be fiddling with running applications */
  242.     if(tpb.ioFlAttrib&0x04) continue;
  243.     
  244.     for(i=0;i<ntt;i++) if(tpb.ioFlFndrInfo.fdType==targType[i]) break;
  245.     if(i<ntt)
  246.         {
  247.         char    saveco,    reso;
  248.         
  249.         saveco=check_only;
  250.         
  251.         rrf=FSpOpenResFile(&tana,fsRdWrPerm);
  252.         if(!rrf || rrf==-1)
  253.             {
  254.             rrf=FSpOpenResFile(&tana,fsRdPerm);
  255.             if(!rrf || rrf==-1) continue;
  256.             // file is locked
  257.             check_only=1;
  258.             }
  259.         
  260.         reso=RepairApp(rrf);
  261.         CloseResFile(rrf);
  262.         
  263.         if(reso)
  264.             {
  265.             if(!saveco && check_only)
  266.                 {
  267.                 ParamText(tana.name,nil,nil,nil);
  268.                 Alert(132,nil);
  269.                 if(logef) WriteString(logef,
  270.                     "\p• Following app is infected but was not repaired: ");
  271.                 }
  272.             SetDialogItemText(filnh,tana.name);
  273.             ufi=0;
  274.             numo++;
  275.             
  276.             // If ParamText was called for another alert it could stuff us up here
  277.             SetPort(logo);
  278.             ParamText(saveco?"\pinfected":"\prepaired",nil,nil,nil);
  279.             DrawDialog(logo);
  280.             
  281.             if(logef) WriteAppPath();
  282.             }
  283.         toto++;
  284.         check_only=saveco;
  285.         
  286.         SetPort(logo);
  287.         
  288.         if(!(ufi&0xF))
  289.             {
  290.             NumToString(numo,nums);
  291.             SetDialogItemText(numh,nums);
  292.             NumToString(toto,tots);
  293.             SetDialogItemText(toth,tots);
  294.             }
  295.         ufi++;
  296.         }
  297.     }
  298. }
  299.  
  300.  
  301.  
  302. /* Writes lantana's path to logef */
  303. void WriteAppPath(void)
  304. {
  305. HFileInfo    tpb;
  306. Str63        dina;
  307. long        *bsp;
  308.  
  309.  
  310. tpb.ioCompletion=nil;
  311. tpb.ioVRefNum=lantana->vRefNum;
  312. tpb.ioNamePtr=dina;
  313. tpb.ioFDirIndex=-1;
  314.  
  315. bsp=(long*)bigstak;        // 8000-deep folders? no problem :-)
  316. *bsp=lantana->parID;
  317.  
  318. while(*bsp!=fsRtDirID)
  319.     {
  320.     tpb.ioDirID=*bsp;
  321.     PBGetCatInfoSync((CInfoPBRec*)&tpb);
  322.     if(tpb.ioResult) break;
  323.     *(++bsp)=tpb.ioFlParID;
  324.     }
  325.  
  326. // It's too late tonight to figure out how to construct the pathname
  327. // backwards in the buffer. And this bit doesn't need to be fast.
  328.  
  329. WriteString(logef,volnm);
  330. WriteString(logef,"\p:");
  331. for(bsp--;bsp>=(long*)bigstak;bsp--)
  332.     {
  333.     tpb.ioDirID=*bsp;
  334.     PBGetCatInfoSync((CInfoPBRec*)&tpb);
  335.     
  336.     WriteString(logef,dina);
  337.     WriteString(logef,"\p:");
  338.     }
  339. WriteString(logef,lantana->name);
  340. WriteString(logef,"\p\r");
  341. }
  342.  
  343.  
  344. /* Yes, I know, I should've made it a dialog or put in more buttons or something */
  345. pascal Boolean AlertKludge(DialogPtr theDialog, EventRecord *theEvent, short *itemHit)
  346. {
  347. ControlHandle    abh,    bbh;
  348. KeyMap            kk;
  349. Boolean            tobecheck;
  350.  
  351. GetKeys(kk);
  352. tobecheck = (kk[1]&0x8000)?1:0;
  353.  
  354. if(theEvent->what==keyDown && (theEvent->message&charCodeMask)==13)
  355.     {
  356.     GetDialogItem(theDialog,1,nil,(Handle*)&abh,nil);
  357.     HiliteControl(abh,1);
  358.     Delay(8,nil);
  359.     HiliteControl(abh,0);
  360.     
  361.     *itemHit=1;
  362.     return true;
  363.     }
  364.  
  365. if(theEvent->what==mouseDown) lmdco=check_only;
  366.  
  367. if(tobecheck==check_only) return false;
  368.  
  369. GetDialogItem(theDialog,2,nil,(Handle*)&abh,nil);
  370. GetDialogItem(theDialog,3,nil,(Handle*)&bbh,nil);
  371.  
  372. if(check_only=tobecheck)    // intentional single equal-sign!
  373.     {
  374.     SetControlTitle(abh,"\pExamine One App…");
  375.     SetControlTitle(bbh,"\pExamine All Volumes");
  376.     }
  377. else
  378.     {
  379.     SetControlTitle(abh,"\pRepair One App…");
  380.     SetControlTitle(bbh,"\pRepair All Volumes");
  381.     }
  382.  
  383. if(theEvent->what==mouseDown) lmdco=check_only;
  384.  
  385. return false;
  386. }
  387.  
  388.  
  389.  
  390. void DecodeVirus(void)
  391. {
  392. StandardFileReply    rep;
  393. Handle                org,    dst;
  394. short                rrf,    i;
  395.  
  396. StandardGetFile(nil,-1,nil,&rep);
  397. if(!rep.sfGood) ExitToShell();
  398.  
  399. rrf=FSpOpenResFile(&rep.sfFile,fsRdWrPerm);
  400. org=Get1Resource('INIT',33);
  401. HLock(org);
  402. dst=NewHandle(GetHandleSize(org));
  403. HLock(dst);
  404.  
  405. BlockMoveData(*org,*dst,GetHandleSize(org));
  406.  
  407. for(i=0x0A;i<0x6EE+0x0A;i++) (*dst)[i]^=0xCC;
  408.  
  409. HUnlock(dst);
  410. HUnlock(org);
  411.  
  412. AddResource(dst,'INIT',0,nil);
  413.  
  414. CloseResFile(rrf);
  415. }